/*
 * Ant Group
 * Copyright (c) 2004-2024 All Rights Reserved.
 */
package com.alipay.zmdepositdemo.service.create;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayFundAuthOrderAppFreezeModel;
import com.alipay.api.domain.PostPayment;
import com.alipay.api.request.AlipayFundAuthOrderAppFreezeRequest;
import com.alipay.api.response.AlipayFundAuthOrderAppFreezeResponse;
import com.alipay.zmdepositdemo.model.CreditOrderModel;
import com.alipay.zmdepositdemo.model.OpenResponse;
import com.alipay.zmdepositdemo.util.AlipayApiCallback;
import com.alipay.zmdepositdemo.util.AlipayApiTemplate;
import com.alipay.zmdepositdemo.util.AlipaySdkUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 创建免押订单
 *
 * 简要流程 <详情请参考注释中接入指南/>
 * 1、【研发】【商家】创建免押订单，获得页面下单链接URL
 * 2、      【用户】在下单受理页面中下单
 * 3、【研发】【商家】确认订单通知，主动返回success
 *
 * @author zhangjian
 * @version DepositOrderCreateServiceImpl.java, v 0.1 2024年06月17日 14:36 zhangjian
 * @see <a href="https://opendocs.alipay.com/open/03w0a8?pathHash=d3c885ce#创建免押订单流程/"> 接入指南-创建免押订单流程</a>
 */
@Service
public class DepositOrderCreateServiceImpl implements DepositOrderCreateService {

    private static final Logger logger = LogManager.getLogger(DepositOrderCreateServiceImpl.class);

    private AlipaySdkUtil alipaySdkUtil;

    @Autowired
    public void ConstructorAlipaySdkUtil(AlipaySdkUtil alipaySdkUtil) {
        this.alipaySdkUtil = alipaySdkUtil;
    }

    /**
     * 创建免押订单
     *
     * @param creditOrderModel 信用订单模型
     * @return 页面下单链接URL
     */
    @Override
    public OpenResponse<String> createDepositOrder(CreditOrderModel creditOrderModel) {

        return AlipayApiTemplate.execute(new AlipayApiCallback<String, AlipayFundAuthOrderAppFreezeResponse>() {

            @Override
            public AlipayFundAuthOrderAppFreezeResponse process() throws AlipayApiException {
                AlipayFundAuthOrderAppFreezeRequest request = CreateDepositOrderRequestBuilder(creditOrderModel);
                logger.info(
                        "com.alipay.zmdepositdemo.service.create.DepositOrderCreateServiceImpl.createDepositOrder,"
                                + "AlipayFundAuthOrderAppFreezeRequest:"
                                +
                                JSON.toJSONString(request));

                return alipaySdkUtil.execute(request);
            }

            @Override
            public String getData(AlipayFundAuthOrderAppFreezeResponse response) {
                return response.getOrderStr();
            }

            @Override
            public String getApiName() {
                return "创建免押订单-alipay.fund.auth.order.app.freeze(线上资金授权冻结接口)";
            }
        });
    }

    /**
     * 创建免押订单入参构造
     *
     * @param creditOrderModel 信用订单模型
     * @return AlipayFundAuthOrderAppFreezeRequest
     */
    private AlipayFundAuthOrderAppFreezeRequest CreateDepositOrderRequestBuilder(CreditOrderModel creditOrderModel) {

        AlipayFundAuthOrderAppFreezeRequest request = new AlipayFundAuthOrderAppFreezeRequest();
        AlipayFundAuthOrderAppFreezeModel model = new AlipayFundAuthOrderAppFreezeModel();

        /** 设置后付费项目，根据3种模式，3选一的方式设置：
         * 当免押模式为纯免押时：DEPOSIT_ONLY ，无需设置postPayments
         *  当免押模式为纯免押时：POSTPAY ，填入方式如下1：
         *  当免押模式为纯免押时：POSTPAY_UNCERTAIN ，填入方式如下2：
         */
        // 芝麻免押重要入参：设置免押受理台模式
        model.setDepositProductMode(creditOrderModel.getDepositProductMode());
        List<PostPayment> postPayments = new ArrayList<PostPayment>();

        // 当免押模式为纯免押时：POSTPAY ， 填入方式如下：
        if (creditOrderModel.getDepositProductMode().equals("POSTPAY")) {
            PostPayment postPayments0 = new PostPayment();
            postPayments0.setAmount(creditOrderModel.getPostPaymentsModel().getProductModeAmount());
            postPayments0.setName(creditOrderModel.getPostPaymentsModel().getProductModeName());
            // 当免押模式为纯免押时：POSTPAY ，description为空
            postPayments0.setDescription("");
            postPayments.add(postPayments0);
            model.setPostPayments(postPayments);
        }

        // 当免押模式为后付费金额未知模式时：POSTPAY_UNCERTAIN ，填入方式如下：
        if (creditOrderModel.getDepositProductMode().equals("POSTPAY_UNCERTAIN")) {
            List<PostPayment> postPayments_1 = new ArrayList<PostPayment>();
            PostPayment postPayments1 = new PostPayment();
            postPayments1.setName(creditOrderModel.getPostPaymentsModel().getProductModeAmount());
            // 当免押模式为纯免押时：POSTPAY_UNCERTAIN ，setAmount为空
            postPayments1.setAmount("");
            postPayments1.setDescription(creditOrderModel.getPostPaymentsModel().getProductModeDescription());
            postPayments.add(postPayments1);
            model.setPostPayments(postPayments_1);
        }

        // 芝麻免押重要入参：设置芝麻免押必须的业务扩展参数
        model.setExtraParam(creditOrderModel.getCreditServiceStr());
        // 芝麻免押重要入参：设置订单标题
        model.setOrderTitle(creditOrderModel.getOrderTitle());

        // 设置需要冻结的金额
        model.setAmount(creditOrderModel.getTotalAmount());
        //// 设置收款账户的支付宝用户号
        //model.setPayeeUserId(creditOrderModel.getPayeeUserId());
        // 设置商户授权资金订单号
        model.setOutOrderNo(creditOrderModel.getOutOrderNo());
        // 设置销售产品码: 预授权支付产品码
        model.setProductCode(creditOrderModel.getProductCode());

        //// 设置收款账户的支付宝登录号（email或手机号）
        //model.setPayeeLogonId(creditOrderModel.getPayeeLogonId());

        // 设置无特殊需要请勿传入
        model.setEnablePayChannels(creditOrderModel.getEnablePayChannels());
        // 设置无特殊需要请勿传入
        model.setIdentityParams(creditOrderModel.getIdentityParams());
        // 设置业务参数
        model.setBusinessParams(creditOrderModel.getBusinessParams());
        // 设置预授权订单相对超时时间
        model.setTimeoutExpress(creditOrderModel.getTimeoutExpress());
        //// 设置无特殊需要请勿传入
        //model.setDisablePayChannels(creditOrderModel.getDisablePayChannels());
        // 设置商户本次资金操作的请求流水号
        model.setOutRequestNo(creditOrderModel.getOutRequestNo());

        request.setBizModel(model);

        return request;
    }

}